//
//  BaseTableView.swift
//  DYSwiftFramework
//
//  Created by huangdeyu on 2021/10/19.
//  Copyright © 2021 none. All rights reserved.
//

import Foundation
import UIKit


enum PageStatus {
    case notDetermine  // 未知状态，一般显示loadding 或者骨架屏
    case noData
    case noNetwork
    case normal
}

/// 空视图必须符合的协议，空视图类型
protocol EmptyViewProtocol where Self : UIView {
    var emptyType:PageStatus {get set}
    var onReloadHandler:(()->Void)? {get set}
}

/// 数据模型需要符合这个协议，添加一个缓存高度， 之所以用AnyObject，目的是为修改引用对象的值，结构体目前做不到,所以模型必须是类
protocol ModelCacheHeightProtocol:AnyObject{
    var cacheHeight:CGFloat? {set get}
    var cellIndex:Int {set get}
}


// 创建一个默认的空视图
class DefalutEmptyView: UIView, EmptyViewProtocol{
    
    var onReloadHandler: (() -> Void)?
    var emptyType: PageStatus = .notDetermine {
        willSet {
            self.isHidden = false
            img.isHidden = false
            button.isHidden = false
            descLbl.isHidden = false
            indicatorView.isHidden = true
            if indicatorView.isAnimating {
                indicatorView.stopAnimating()
            }
            switch newValue {
            case .normal:
                self.isHidden = true
            case .noData:
                self.img.image = UIImage.init(named: "yjf_empty_white")
                button.isHidden = true
                descLbl.text = "暂无数据"
            case .noNetwork:
                img.image = UIImage.init(named: "yjf_error_white")
                descLbl.text = "发生错误"
            case .notDetermine:
                indicatorView.isHidden = false
                if !indicatorView.isAnimating {
                    indicatorView.startAnimating()
                }
                img.isHidden = true
                descLbl.isHidden = true
                button.isHidden = true
            }
        }
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    lazy var img = UIImageView()
    lazy var indicatorView = UIActivityIndicatorView(style: .gray)
    lazy var descLbl = UILabel.init()
    lazy var button = UIButton.init(type: .custom)
    
    init() {
        super.init(frame: CGRect.zero)
        img.contentMode = .scaleAspectFit
        img.image = UIImage.init(named: "yjf_empty_white")
        addSubview(img)
        
        descLbl.font = UIFont.systemFont(ofSize: 14)
        descLbl.setContentHuggingPriority(.required, for: .horizontal)
        descLbl.numberOfLines = 1
        descLbl.textColor = UIColor.init(hex: 0xaaaaaa)
        addSubview(descLbl)
        
        button.setTitle("重新加载", for: .normal)
        button.setTitleColor(UIColor.init(hex: 0xaaaaaa), for: .normal)
        button.titleLabel?.font = UIFont.systemFont(ofSize: 13)
        button.layer.borderColor = UIColor.init(hex: 0xaaaaaa)?.cgColor
        button.layer.borderWidth = 0.5
        button.layer.cornerRadius = 15
        button.onTap = { [weak self] (button) in
            if let loadder = self?.onReloadHandler {
                loadder()
            }
        }
        addSubview(button)
        
        self.indicatorView.hidesWhenStopped = true
        
        addSubview(indicatorView)
        
        setupUI()
    
            
    }
    
    
    func setupUI()  {
        let containerView = UIView.init()
        addSubview(containerView)
        containerView.snp.makeConstraints { (make) in
            make.center.equalToSuperview()
            make.edges.equalToSuperview()
        }
        img.snp.makeConstraints { (make) in
            make.top.left.right.equalTo(containerView)
            make.width.height.equalTo(100)
        }
        descLbl.snp.makeConstraints { (make) in
            make.centerX.equalTo(containerView)
            make.top.equalTo(img.snp.bottom).offset(12)
        }
        button.snp.makeConstraints { (make) in
            make.centerX.equalTo(containerView)
            make.top.equalTo(descLbl.snp.bottom).offset(12)
            make.width.equalTo(100)
            make.height.equalTo(30)
            make.bottom.equalTo(containerView)
        }
        indicatorView.snp.makeConstraints { (make) in
            make.center.equalToSuperview()
        }
    }

}


/// tableView的封装
/// 分页机制
/// 高度缓存机制[如果后面有section或者header缓存的需求也可以再补充]
/// 空页面处理机制
/// 只能处理单section，多section的业务处理不了，[如果可以改为header的形式是最好的]
class BaseTableView: UIView,UITableViewDelegate,UITableViewDataSource{

    let tableView:UITableView = UITableView.init()
    var pageIndex = 0
    var pageSize = 10
    private var originPageIndex = 0
    var models:[ModelCacheHeightProtocol?] = []
    var onLoad:((Int)->Void)?
    var emptyView:EmptyViewProtocol? // 空数据视图
    
    required init?(coder: NSCoder) {
        super.init(coder: coder)
    }
    /// 初始化
    /// - Parameters:
    ///   - pageIndex: 初始索引
    ///   - pageSize: 页面大小
    ///   - sectionCount: section数量
    ///   - onLoad: 触发刷新的回调
    init(pageIndex:Int = 0,
         pageSize:Int = 10,
         emptyView:EmptyViewProtocol? = DefalutEmptyView()) {
        super.init(frame: CGRect.zero)
        tableView.delegate = self
        tableView.dataSource = self
        tableView.header = JRefreshNormalHeader.headerWithRefreshingBlock({[weak self] in
            if let load = self?.onLoad{
               
                self?.pageIndex = self?.originPageIndex ?? 0
                load(self?.originPageIndex ?? 0)
                debugPrint("下拉刷新中....")
            }
        })
        tableView.footer = JRefreshAutoNormalFooter.footerWithRefreshingBlock({ [weak self] in
            if let load = self?.onLoad{
                
                self?.pageIndex += 1
                load(self?.pageIndex ?? 0)
                debugPrint("上拉加载中...\(self?.pageIndex ?? 0)")
            }
        })

        if #available(iOS 11.0, *) {
            tableView.contentInsetAdjustmentBehavior = .never
        } else {
            
        }
        
        tableView.separatorStyle = .none
        addSubview(tableView)
        tableView.snp.makeConstraints { (m) in
            m.edges.equalToSuperview()
        }
        
        self.pageIndex = pageIndex
        self.originPageIndex = self.pageIndex
        self.pageSize = pageSize
        self.emptyView = emptyView
        setupEmpty()
    }
    private func setupEmpty(){
        if emptyView == nil {
            return
        }
        tableView.addSubview(emptyView!)
        emptyView?.emptyType = .notDetermine
        emptyView?.snp.makeConstraints({ (make) in
            make.center.equalToSuperview()
        })
        emptyView?.onReloadHandler = { () in
            
        }
    }
    
    
    // 处理分页数据的方式,分页数据必须是最后一个section的数据
    func dealWith(data:[ModelCacheHeightProtocol?]?, error:Error?) {
        self.tableView.header?.endRefreshing()
        self.tableView.footer?.endRefreshing()
        // 当前tableview的状态:[无数据，索引为初始索引]
        if self.models.isEmpty {
            // 还发生了错误:[展示错误数据]
            if let _ = error {
                self.emptyView?.emptyType = .noNetwork
                self.pageIndex = self.originPageIndex
                self.tableView.reloadData()
                return
            }
            // 无数据:[展示空页面]
            if data == nil || data?.count == 0{
                self.emptyView?.emptyType = .noData
                self.pageIndex = self.originPageIndex
                self.tableView.reloadData()
                return
            }
            // 正常返回
            self.emptyView?.emptyType = .normal
            self.models = data!
            self.tableView.reloadData()
            return
        }
        // 当前列表状态中已经有数据了
        self.emptyView?.emptyType = .normal
        // 发生了错误[索引-1]不进行其他任何操作
        if let _ = error {
            self.pageIndex -= 1
            self.pageIndex = self.pageIndex < self.originPageIndex ? self.originPageIndex : self.pageIndex
            return
        }
        if data == nil || data?.count == 0 {
            // 相当于下拉刷新操作
            if self.pageIndex == self.originPageIndex {
                self.emptyView?.emptyType = .noData
                self.models = []
                self.tableView.reloadData()
            } else { // 相当于上拉加载操作:[展示无更多数据]
                tableView.footer?.endRefreshingWithNoMoreData()
                self.tableView.reloadData()
            }
            return
        }
        // 如果当前数据不为空，加载的数据也不为空
        // 下拉刷新操作
        if self.pageIndex == self.originPageIndex {
            self.models = data!
        } else { // 上拉加载操作[这个数据怎么装载呢]
            models.append(contentsOf: data!)
        }
        tableView.reloadData()
    }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return models.count
    }
    
    // 子类重写
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        return UITableViewCell.init()
    }
    
    // 在这里缓存高度
    func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
        let model = models[indexPath.row]
        let height = cell.frame.size.height
        model?.cacheHeight = height
    }
    
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        let model = models[indexPath.row]
        if let height = model?.cacheHeight {
            return height
        }
        return UITableView.automaticDimension
    }

    func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
        let model = models[indexPath.row]
        if let height = model?.cacheHeight {
            return height
        }
        return UITableView.automaticDimension
    }
}

